package com.xscha.tableforge.repository;

import com.xscha.soyue.common.core.utils.DateUtils;
import com.xscha.tableforge.model.entity.FieldMeta;
import com.xscha.tableforge.model.vo.PageReq;
import com.xscha.tableforge.model.vo.PageResult;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.OrderField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.xscha.tableforge.jooq.tables.FieldMetaTable.FIELD_META;

@Repository
public class FieldMetaRepository {

    private final DSLContext dslContext;

    @Autowired
    public FieldMetaRepository(DSLContext dslContext) {
        this.dslContext = dslContext;
    }

    public List<FieldMeta> findAllByTableId(String tableId) {
        return dslContext.select()
                .from(FIELD_META)
                .where(FIELD_META.TABLE_ID.eq(tableId)
                        .and(FIELD_META.DELETED_TIME.isNull()))
                .orderBy(FIELD_META.CREATED_TIME.asc())
                .fetchInto(FieldMeta.class);
    }

    public Optional<FieldMeta> findById(String id) {
        return dslContext.select()
                .from(FIELD_META)
                .where(FIELD_META.ID.eq(id)
                        .and(FIELD_META.DELETED_TIME.isNull()))
                .fetchOptionalInto(FieldMeta.class);
    }

    public FieldMeta save(FieldMeta fieldMeta) {
        dslContext.insertInto(FIELD_META)
                .set(FIELD_META.ID, fieldMeta.getId())
                .set(FIELD_META.NAME, fieldMeta.getName())
                .set(FIELD_META.DESCRIPTION, fieldMeta.getDescription())
                .set(FIELD_META.OPTIONS, fieldMeta.getOptions())
                .set(FIELD_META.TYPE, fieldMeta.getType())
                .set(FIELD_META.CELL_VALUE_TYPE, fieldMeta.getCellValueType())
                .set(FIELD_META.IS_MULTIPLE_CELL_VALUE, fieldMeta.getIsMultipleCellValue())
                .set(FIELD_META.DB_FIELD_TYPE, fieldMeta.getDbFieldType())
                .set(FIELD_META.DB_FIELD_NAME, fieldMeta.getDbFieldName())
                .set(FIELD_META.NOT_NULL, fieldMeta.getNotNull())
                .set(FIELD_META.IS_UNIQUE, fieldMeta.getIsUnique())
                .set(FIELD_META.IS_PRIMARY, fieldMeta.getIsPrimary())
                .set(FIELD_META.IS_COMPUTED, fieldMeta.getIsComputed())
                .set(FIELD_META.IS_LOOKUP, fieldMeta.getIsLookup())
                .set(FIELD_META.IS_PENDING, fieldMeta.getIsPending())
                .set(FIELD_META.HAS_ERROR, fieldMeta.getHasError())
                .set(FIELD_META.LOOKUP_LINKED_FIELD_ID, fieldMeta.getLookupLinkedFieldId())
                .set(FIELD_META.LOOKUP_OPTIONS, fieldMeta.getLookupOptions())
                .set(FIELD_META.TABLE_ID, fieldMeta.getTableId())
                .set(FIELD_META.VERSION, fieldMeta.getVersion())
                .set(FIELD_META.CREATED_TIME, fieldMeta.getCreatedTime())
                .set(FIELD_META.CREATED_BY, fieldMeta.getCreatedBy())
                .set(FIELD_META.DISPLAY_ORDER, fieldMeta.getDisplayOrder())
                .execute();
        return fieldMeta;
    }

    public FieldMeta update(FieldMeta fieldMeta) {
        dslContext.update(FIELD_META)
                .set(FIELD_META.NAME, fieldMeta.getName())
                .set(FIELD_META.DESCRIPTION, fieldMeta.getDescription())
                .set(FIELD_META.OPTIONS, fieldMeta.getOptions())
                .set(FIELD_META.TYPE, fieldMeta.getType())
                .set(FIELD_META.CELL_VALUE_TYPE, fieldMeta.getCellValueType())
                .set(FIELD_META.IS_MULTIPLE_CELL_VALUE, fieldMeta.getIsMultipleCellValue())
                .set(FIELD_META.DB_FIELD_TYPE, fieldMeta.getDbFieldType())
                .set(FIELD_META.NOT_NULL, fieldMeta.getNotNull())
                .set(FIELD_META.IS_UNIQUE, fieldMeta.getIsUnique())
                .set(FIELD_META.IS_PRIMARY, fieldMeta.getIsPrimary())
                .set(FIELD_META.IS_COMPUTED, fieldMeta.getIsComputed())
                .set(FIELD_META.IS_LOOKUP, fieldMeta.getIsLookup())
                .set(FIELD_META.IS_PENDING, fieldMeta.getIsPending())
                .set(FIELD_META.HAS_ERROR, fieldMeta.getHasError())
                .set(FIELD_META.LOOKUP_LINKED_FIELD_ID, fieldMeta.getLookupLinkedFieldId())
                .set(FIELD_META.LOOKUP_OPTIONS, fieldMeta.getLookupOptions())
                .set(FIELD_META.VERSION, fieldMeta.getVersion())
                .set(FIELD_META.LAST_MODIFIED_BY, fieldMeta.getLastModifiedBy())
                .set(FIELD_META.LAST_MODIFIED_TIME, fieldMeta.getLastModifiedTime())
                .set(FIELD_META.DISPLAY_ORDER, fieldMeta.getDisplayOrder())
                .where(FIELD_META.ID.eq(fieldMeta.getId()))
                .execute();
        return fieldMeta;
    }

    public void softDelete(String id, String userId) {
        dslContext.update(FIELD_META)
                .set(FIELD_META.DELETED_TIME, DateUtils.nowTimeStamp().toLocalDateTime())
                .set(FIELD_META.LAST_MODIFIED_BY, userId)
                .set(FIELD_META.LAST_MODIFIED_TIME, DateUtils.nowTimeStamp().toLocalDateTime())
                .where(FIELD_META.ID.eq(id))
                .execute();
    }

    public PageResult<FieldMeta> findPageByTableId(String tableId, PageReq pageRequest) {
        // 计算总记录数
        int total = dslContext.selectCount()
                .from(FIELD_META)
                .where(FIELD_META.TABLE_ID.eq(tableId)
                        .and(FIELD_META.DELETED_TIME.isNull()))
                .fetchOneInto(Integer.class);
        
        // 构建排序条件
        List<OrderField<?>> orderFields = new ArrayList<>();
        if (pageRequest.getOrderBy() != null && !pageRequest.getOrderBy().isEmpty()) {
            Field<?> orderField = FIELD_META.field(pageRequest.getOrderBy());
            if ("desc".equalsIgnoreCase(pageRequest.getOrderDirection())) {
                orderFields.add(orderField.desc());
            } else {
                orderFields.add(orderField.asc());
            }
        } else {
            // 默认按order字段排序
            orderFields.add(FIELD_META.DISPLAY_ORDER.asc());
        }
        
        // 查询分页数据
        List<FieldMeta> records = dslContext.select()
                .from(FIELD_META)
                .where(FIELD_META.TABLE_ID.eq(tableId)
                        .and(FIELD_META.DELETED_TIME.isNull()))
                .orderBy(orderFields)
                .limit(pageRequest.getPageSize())
                .offset((pageRequest.getPageNum() - 1) * pageRequest.getPageSize())
                .fetchInto(FieldMeta.class);
        
        return PageResult.of(records, total, pageRequest.getPageNum(), pageRequest.getPageSize());
    }
}